/**
 * @fileOverview Effect classes
 * @requires app
 */

(function() {
	/**
	 * @class Basic class for effects
	 * @extends app.Basic
	 * @borrows app.Basic.extend as extend
	 *
	 * @property {String} name Effect name
	 * @property {String} attribute Attribute ID affected by this effect
	 * @property {Number|String|Object} amount Effect amount
	 * @property {Number} duration Effect duration in milliseconds
	 * @property {Number} period Period between each effect's action in milliseconds
	 * @property {Number} [type={@link app.Effect.TYPE_DAMAGE}] Effect type
	 * @property {Number} [target={@link app.Effect.TARGET_ENEMY}] Target of this effect
	 * @property {Boolean} [group=false] Group skill flag
	 */
	app.Effect = app.Basic.extend({
		/** @lends app.Effect.prototype */
		
		/**
		 * Effect initialization
		 *
		 * @param {Object} options Effect configuration
		 * @param {String} options.name Effect name
		 * @param {String} options.attribute Attribute affected by this effect
		 * @param {Number|String|Object} options.amount Amount
		 * @param {Number} options.duration Effect duration in millisecons
		 * @param {Number} options.period Period between each effect's action in milliseconds
		 */
		init : function(options) {
			var defaults = {
				attribute : '',
				duration : 0,
				period : 0,
				type : app.Effect.TYPE_DAMAGE,
				target : app.Effect.TARGET_ENEMY,
				group : false
			};
			
			options || (options = {});
			
			options = app.extend({}, defaults, options);
			
			for (var key in options) {
				this[key] = options[key];
			}
		},
		
		/**
		 * Get value of effect.<br>If amount is a min/max value then it will be a random value between min and max
		 *
		 * @returns {Object} Effect value
		 */
		getAmount : function() {
			var value;
			
			value = (isFinite(this.amount) || typeof this.amount == 'string') ? this.amount : (Math.floor(Math.random() * this.amount.max) + this.amount.min);
			
			return {
				attribute : this.attribute,
				amount : value,
				positive : this.type == app.Effect.TYPE_BUFF
			};
		},
		
		/**
		 * Use the effect on given target
		 *
		 * @param {app.Unit} caster Unit that casts this effect
		 * @param {app.Unit} target Unit on which this effect will be used
		 */
		use : function(caster, target) {
			
		},
		
		/**
		 * Get string representation of effect
		 *
		 * @returns {String} String representation of effect
		 */
		toString : function() {
			return this.name;
		}
	},
	
	/** @lends app.Effect */
	{
		/**
		 * Effect can be applied to caster
		 * @constant
		 */
		TARGET_SELF : 0,
		/**
		 * Effect can be applied to caster's ally
		 * @constant
		 */
		TARGET_ALLY : 1,
		/**
		 * Effect can be applied to caster's enemy
		 * @constant
		 */
		TARGET_ENEMY : 2,
		/**
		 * Damage effect
		 * @constant
		 */
		TYPE_DAMAGE : 0,
		/**
		 * Buff effect
		 * @constant
		 */
		TYPE_BUFF : 1,
		/**
		 * Debuff effect
		 * @constant
		 */
		TYPE_DEBUFF : 2
	});
	
	/* ************************************************************************************* */
	
	/**
	 * Effect class (v2)<br />
	 * As all effects are periodical or have duration, they can be based on {@link app.Timer} class.
	 *
	 * @class Effect class (v2)
	 * @extends app.Timer
	 * @borrows app.Basic.extend as extend
	 *
	 * @property {Object} amounts List of amounts that will be applied to target
	 * @property {Boolean} [positive=true] Flag if this effect is positive or not
	 */
	app.Effect2 = app.Timer.extend({
		/** @lends app.Effect2.prototype */
		
		/**
		 * Effect initialization
		 */
		init : function(options) {
			this.positive = true;
			this.amounts = {};
		},
		
		getValue : function() {
			
		}
	});
	
	/* ************************************************************************************* */
	
	/**
	 * @class Effects manager
	 * @extends app.Manager
	 */
	app.EffectMgr = new app.Manager(app.Effect);
})();